package etnorservice.etnor_service.controller;

import etnorservice.etnor_service.domain.dto.ParamsDTO;
import etnorservice.etnor_service.domain.po.ApiPublishConfig;
import etnorservice.etnor_service.domain.po.ApiRequestLog;
import etnorservice.etnor_service.domain.po.ApiToken;
import etnorservice.etnor_service.domain.vo.ApiDetailsVO;
import etnorservice.etnor_service.result.Result;
import etnorservice.etnor_service.service.IApiService;
import etnorservice.etnor_service.utils.ApiTokenUtil;
import etnorservice.etnor_service.utils.HttpUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: cc
 * @Date: 2024/11/29/14:30
 * @Description:这是接口请求的总控制器，具备网关作用，请求以/open/api/{apiid}开头
 * @en:This is the main controller for API requests, serving as a gateway.
 * Requests start with /open/api/{apiid}.
 **/
@RestController
public class CenterApiController {
    @Autowired
    IApiService apiService;
    @Autowired
    ApiTokenUtil apiTokenUtil;


    //调度器，接受请求，参数校验，token校验，转发请求，返回结果
    @GetMapping("/open/api/{apiid}")
    public Result getResData(@PathVariable("apiid") String apiid,
                             @RequestParam Map<String, String> params,
                             HttpServletRequest request) throws SQLException {
        System.out.println("参数+parms"+params);
        Result result = new Result();
        ApiDetailsVO apiById = new ApiDetailsVO();
        try {
            apiById = apiService.findApiById(apiid);
        }catch (Exception e){
            result.setMessage("接口不存在");
            result.setCode(404);
            return result;
        }
        ApiPublishConfig apiConfig = apiService.getApiConfig(Long.parseLong(apiid));

        if(apiById==null){
            result.setCode(404);
            result.setMessage("接口不存在，请检查接口地址及参数！");
            return result;
        }
        if(apiById.getNeedToken()==1){

        }
        //todo:这里如果需要研判是否需要token，需要则提示用户缺少token，其实可以设计成本系统的接口需要token
        if(apiConfig==null){
            result.setCode(200);
            result.setMessage("该接口未配置规则，需警慎调用");
        }
        if(apiConfig!=null&&apiConfig.getPublishType()=="full"){
            result.setCode(200);
        }
        //获取api调用次数
        Integer count = apiService.countApiCalls(Long.parseLong(apiid));
        if(apiConfig!=null&&apiConfig.getPublishType().equals("gray") && apiConfig.getRequestThreshold()<count){
            result.setCode(40404);
            result.setMessage("该接口已经超过灰度发布阈值，请联系管理员或者开发方~");
            return result;
        }
        //找到api的参数列表
        List<ParamsDTO> paramsDTOList = apiService.getParams(apiid);
        if(apiById.getNeedToken()==1)//需要token
        {
            ParamsDTO paramsDTO = new ParamsDTO();
            paramsDTO.setParamsName("token");
            paramsDTO.setNeed(1);
            paramsDTOList.add(paramsDTO);
        }
        // 比较参数列表
        boolean isValid = validateParameters(params, paramsDTOList);
        if (!isValid) {
            result.setCode(400400);
            String resultMesg = "";
            for(ParamsDTO paramsDTO:paramsDTOList){
                resultMesg+=paramsDTO.getParamsName()+",";
            }
            result.setMessage("参数不匹配:"+"移除不必要的参数列表?"+"参数列表["+resultMesg+"]");
            return result;
        }
        //token校验
        Long userId = null;
        Long apiId = null;
        try {
             userId = apiTokenUtil.getUserIdFromToken(params.get("token"));
             apiId= apiTokenUtil.getApiIdFromToken(params.get("token"));
        }catch (Exception e){
            result.setCode(500);
            result.setMessage("token格式有问题:"+e.getMessage());
            return result;
        }
        ApiToken apiToken = apiService.findApiToken(apiId, userId);
        if(apiById.getNeedToken()==1&&apiToken==null){
            result.setCode(400);
            result.setMessage("抱歉，您目前无权使用该接口，快去申请该接口的token吧"+"https://etnor.com/doc/auth/apply");
            return result;
        }
        // 记录请求开始时间
        long startTime = System.currentTimeMillis();
        ApiRequestLog apiRequestLog = new ApiRequestLog();
        String response="";
        // 请求开始
        try {
            response= HttpUtil.sendGetRequest(apiById.getApiAddress(), params);
            result.setData(response);
            result.setCode(200);
            apiRequestLog.setRequestResult("成功");
        }catch (Exception e){
            apiRequestLog.setRequestResult("失败");
            apiRequestLog.setError(e.getMessage());
        }
        // 记录请求结束时间
        long endTime = System.currentTimeMillis();
        long responseTime = endTime - startTime;
        // 封装请求日志
        apiRequestLog.setRequestIp(request.getRemoteAddr());
        apiRequestLog.setResponseTime(responseTime);
        apiRequestLog.setResponseData(response);
        apiRequestLog.setRequestType("GET");
        apiRequestLog.setRequestTime(new java.sql.Timestamp(startTime));
        apiRequestLog.setApiid(apiid);
        apiService.insertApiRequestLog(apiRequestLog);
        return result;
    }

    /**
     * 验证传入的参数是否与API配置的参数列表一致
     * @param params 传入的查询参数
     * @param paramsDTOList API配置的参数列表
     * @return 参数是否一致
     */
    private boolean validateParameters(Map<String, String> params, List<ParamsDTO> paramsDTOList) {
        // 检查参数数量是否一致
        if (params.size() != paramsDTOList.size()) {
            return false;
        }

        // 检查每个参数是否存在且值匹配
        for (ParamsDTO paramDTO : paramsDTOList) {
            String paramName = paramDTO.getParamsName();


            if (!params.containsKey(paramName) ) {
                return false;
            }
        }

        return true;
    }
}
